﻿using DryIoc;
using Prism.Commands;
using Prism.Mvvm;
using SECSGEMServices;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection.Metadata;
using System.Runtime.InteropServices.Marshalling;
using System.Windows.Documents;
using System.Windows.Threading;
using ZDevice.Event;
using ZZMES.Data;
using ZZMES.Process;
using ZZMES.TCP;

namespace ZZMES.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "MES通讯服务";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }
        private readonly IEventAggregator eventAggregator;
        private readonly DataProviderService dataProviderService;

        private readonly Dispatcher dispatcher;
        public MainWindowViewModel(IEventAggregator eventAggregator,DataProviderService dataProviderService)
        {
            this.eventAggregator = eventAggregator;
            this.dataProviderService = dataProviderService;
            eventAggregator.GetEvent<TcpEvent>().Subscribe(OnReceiveMsg);
            eventAggregator.GetEvent<SECSEvent>().Subscribe(OnCommunicateChanged);
            eventAggregator.GetEvent<TcpStateEvent>().Subscribe(OnTcpCommunicateChanged);
            messageDocument = new FlowDocument();
            dispatcher = Dispatcher.CurrentDispatcher;
            ipConfigs = new ObservableCollection<CommunicateConfig>(dataProviderService.communicateConfigs.ToArray());
            SecsStatesText = [ "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown", "Unknown"];
            SecsStatesColor = ["Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red"];
            ClientStates = ["Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red", "Red"];
        }

        private void OnTcpCommunicateChanged(TcpStateEventArgs args)
        {
            ClientStates[args.id] = args.state == 1 ? "LimeGreen" : "Red";
        }

        private void OnCommunicateChanged(SECSEventArgs args)
        {
            if(args.EventType == EventType.Communicate) 
            {
                SecsStatesText[args.id] = args.connState;
                if (args.connState == "Communicating")
                {
                    SecsStatesColor[args.id] = "LimeGreen";
                }
                else if (args.connState == "Disabled")
                {
                    SecsStatesColor[args.id] = "red";
                }
                else
                {
                    SecsStatesColor[args.id] = "yellow";
                }
            }
        }

        private ObservableCollection<CommunicateConfig> ipConfigs;
       

        public ObservableCollection<CommunicateConfig> IPConfigs
        {
            get { return ipConfigs; }
            set { SetProperty(ref ipConfigs, value);  }
        }
        private ObservableCollection<string> secsStatesText;
        public ObservableCollection<string> SecsStatesText 
        {
            get { return secsStatesText; }
            set { SetProperty(ref secsStatesText, value); } 
        }
        private ObservableCollection<string> secsStatesColor;
        public ObservableCollection<string> SecsStatesColor
        {
            get { return secsStatesColor; }
            set { SetProperty(ref secsStatesColor, value); }
        }

        private ObservableCollection<string> clientStates;
        public ObservableCollection<string> ClientStates
        {
            get { return clientStates; }
            set { SetProperty(ref clientStates, value); }
        }

        private DelegateCommand saveConfigCommand;

        public DelegateCommand SaveConfigCommand
        {
            get { return saveConfigCommand??new DelegateCommand(() => 
            {
                dataProviderService.communicateConfigs = IPConfigs.ToList();
                dataProviderService.SaveIPConfigs();
            }); }
            set { saveConfigCommand = value; }
        }


        private void OnReceiveMsg(TcpEventArgs args)
        {
            if (!args.msg.Contains("S0F1")) 
                dispatcher.InvokeAsync(() => 
                {
                    string[] config = args.client.Split(':');
                    var device = dataProviderService.communicateConfigs.FirstOrDefault(x=>x.IP == config[0]);
                    string name;
                    if (device!=null)
                    {
                        name = device.Name;
                    }
                    else 
                    {
                        name = "未知的设备";
                    }
                    var paragraph = new Paragraph(new Run(name + "==>" + args.msg + Environment.NewLine));
                    MessageDocument.Blocks.Add(paragraph);
                });
           
        }



        private FlowDocument messageDocument;
        public FlowDocument MessageDocument
        {
            get { return messageDocument ; }
            set { SetProperty(ref messageDocument, value); }
        }
    }
}
